package com.sc.socket.chatroom.server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author shuc001
 * @Date 2019-02-05 13:07
 */
public class TCPProvider implements ClientHandlerCallback{

    private final int port;
    private final ExecutorService forwardingTP;
    private ClientListener clientListener;

    private List<ClientHandler> clientHandlerList = new ArrayList<>();


    public TCPProvider(int port) {
        this.port = port;
        forwardingTP = Executors.newSingleThreadExecutor();
    }

    public boolean start() {
        try {
            clientListener = new ClientListener(port);
            clientListener.start();
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
        return true;
    }

    public void stop() {
        if(clientListener!=null){
            clientListener.exit();
        }
        synchronized (TCPProvider.class) {
            clientHandlerList.forEach(c -> c.exit0());
            clientHandlerList.clear();
        }
        forwardingTP.shutdownNow();
    }

    public synchronized void sendBroad(String str) {
        clientHandlerList.forEach(c->c.send(str));
    }

    @Override
    public synchronized void onSelfClose(ClientHandler clientHandler) {
        clientHandlerList.remove(clientHandler);
    }

    @Override
    public void onNewMsgArrived(final ClientHandler clientHandler,final String msg) {
        System.out.println("收到消息FROM "+clientHandler.getClientInfo()+" msg: "+msg);
        forwardingTP.execute(()->{
            synchronized (TCPProvider.class){
                for (ClientHandler handler : clientHandlerList) {
                    if(handler==clientHandler){
                        continue;
                    }
                    handler.send(msg);
                }
            }
        });
    }

    private  class ClientListener extends Thread {
        private ServerSocket server;
        private boolean done = false;

        public ClientListener(int port) throws IOException {
            server = new ServerSocket(port);
            System.out.println("服务器信息: " + server.getInetAddress() + " P " + server.getLocalPort());
        }

        @Override
        public void run() {
            System.out.println("tcp服务器启动中");
            do {
                Socket client;
                try {
                    client = server.accept();
                } catch (Exception e) {
                    continue;
                }
                ClientHandler handler;
                try {
                    handler = new ClientHandler(client,TCPProvider.this);
                    handler.readToPrint();
                    synchronized (TCPProvider.class) {
                        clientHandlerList.add(handler);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println("客户端连接异常");
                }
            } while (!done);
            System.out.println("服务器关闭");
        }

        public void exit() {
            done = true;
            try {
                server.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }
}
